package org.gatorojo.servlet;

import java.util.List;

import java.io.IOException;
import java.io.PrintWriter;

//import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpSession;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.gatorojo.enumerations.Actions;
import org.gatorojo.exception.GatoRojoException;
import org.gatorojo.model.Product;
import org.gatorojo.dao.ProductService;

public class GatoRojoPrintWriter extends HttpServlet {
	
	private static final long serialVersionUID = 1L;
	private String contextPath;

    public void doGet (HttpServletRequest request,
                       HttpServletResponse response)
    throws ServletException, IOException
    {
    	Actions action = Actions.valueOf(request.getParameter("action"));
    	
    	ProductService service = new ProductService();
    	
    	PrintWriter out = response.getWriter();
    	HttpSession session = (HttpSession)request.getSession();
    	//RequestDispatcher dispatcher = getServletContext().getRequestDispatcher("/GatoRojoPrintWriter?action=LIST");
    	contextPath = request.getContextPath();
    	StringBuilder content = new StringBuilder();
    	String message = null;
    	
    	// Variables para contener los datos enviados en forma de parametros.
    	int code = 0;
    	String name = "";
    	double stock = 0.0;
    	
    	// Variable para contener en forma de producto los datos enviados como parametros.
    	Product product = null;
    	
    	switch(action) {
    	case LIST:
    		message = (String) session.getAttribute("message");
    		if(message != null)
    			content.append(message);
    		try {
    			content.append("<div class=\"lista\">");
	    			content.append(writeProductList(service.listProduct()));
	    		content.append("</div");
	    		content.append("<div class=\"actions\">");
		    		content.append(writeAddForm());
		    		content.append("<br/>");
		    		content.append(writeUpdateForm());
		    		content.append("<br/>");
		    		content.append(writeDeleteProductForm());
	    		content.append("</div");
	    		out.print(buildResponse("List Product", content.toString()));
    		} catch(GatoRojoException e) {
    			response.sendRedirect(contextPath + "/view/error.html");
    		}
    		break;
    	case SHOW_ADD:
    		content.append(writeAddProductForm());
    		out.print(buildResponse("Add Product", content.toString()));
    		break;
    	case ADD:
    		code = Integer.parseInt((String)request.getParameter("productCode"));
    		name = (String)request.getParameter("productName");
    		stock = Double.parseDouble((String)request.getParameter("productStock"));
    		product = new Product(code,name,stock);
    		service.addProduct(product);    		    	
    		session.setAttribute("message", writeMessage("Product added successfully!"));
    		response.sendRedirect(contextPath +"/GatoRojoPrintWriter?action=LIST");    		    		    		    		   
    		break;
    	case CANCEL_ADD:
    		session.setAttribute("message", writeMessage("Add product canceled!"));
    		response.sendRedirect(contextPath +"/GatoRojoPrintWriter?action=LIST");    	
    		break;
    	case SHOW_DELETE:
    		code = Integer.parseInt((String)request.getParameter("productCode"));
    		content.append(writeConfirmDeleteProductForm(code));
    		out.print(buildResponse("Add Product", content.toString()));
    		break;    	
    	case DELETE:
    		code = Integer.parseInt((String)request.getParameter("productCode"));    		
    		service.deleteProduct(code);
    		session.setAttribute("message", writeMessage("Product deleted successfully!"));
    		response.sendRedirect(contextPath +"/GatoRojoPrintWriter?action=LIST");
    		break;
    	case CANCEL_DELETE:    		
    		session.setAttribute("message", writeMessage("Delete product canceled!"));
    		response.sendRedirect(contextPath +"/GatoRojoPrintWriter?action=LIST");
    		break;
    	case SHOW_UPDATE:
    		product = service.readProduct(Integer.parseInt((String)request.getParameter("productCode")));
    		content.append(writeUpdateProductForm(product));
    		out.print(buildResponse("Add Product", content.toString()));
    		break;
    	case UPDATE:
    		code = Integer.parseInt((String)request.getParameter("productCode"));
    		name = (String)request.getParameter("productName");
    		stock = Double.parseDouble((String)request.getParameter("productStock"));
    		product = new Product(code,name,stock);    		
    		service.updateProduct(product);    		    	
    		session.setAttribute("message", writeMessage("Product updated successfully!"));
    		response.sendRedirect(contextPath +"/GatoRojoPrintWriter?action=LIST");    		
    		break;
    	case CANCEL_UPDATE:    		
    		session.setAttribute("message", writeMessage("Update product canceled!"));
    		response.sendRedirect(contextPath +"/GatoRojoPrintWriter?action=LIST");
    		break;
    		default:
    			response.sendRedirect(contextPath +"/view/error.html");    			
    	}
    	
    	response.setContentType("text/html");
		out.close();
    }
    
    // Metodos de uso general para el servlet. Se utilizan para renderizar el contenido de cada vista.
    
    // Metodo que renderiza toda la respuesta para una vista.
    public String buildResponse(String title, String body) {
    	StringBuilder responseContent = new StringBuilder();
    	responseContent.append("<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>");
    	responseContent.append("<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">");
    	responseContent.append("<html>");
    	responseContent.append(writeHeader(title));
    	responseContent.append(writeBody(body));    	
    	responseContent.append("</html>");
    	return responseContent.toString();
    }
    
    // Metodo que renderiza el header de una vista.
    public String writeHeader(String title) {    	    	   
    	StringBuilder headerContent = new StringBuilder();
    	headerContent.append("<head>");    	
    	headerContent.append("<title>");    	
    	headerContent.append(title);
    	headerContent.append("</title>");
    	headerContent.append(writeStyle());
    	headerContent.append(writeJavascript());
    	headerContent.append("</head>");
    	return headerContent.toString();    	
    }
    
    // Metodo que renderiza los estilos de una vista.
    public String writeStyle() {
    	StringBuilder cssContent = new StringBuilder();
    	cssContent.append("<link rel=\"stylesheet\" href=\"" + contextPath +"/view/css/gatorojo.css\" type=\"text/css\" media=\"screen\"/>");    	
    	cssContent.append("<style type=\"text/css\">");    	
    	cssContent.append("</style>");    	
    	return cssContent.toString();
    }
    
    // Metodo que renderiza los scripts de una vista.
    public String writeJavascript() {
    	StringBuilder jsContent = new StringBuilder();
    	jsContent.append("<script type=\"text/javascript\" src=\"" + contextPath +"/view/js/jquery-1.4.2.min.js\" charset=\"utf-8\"></script>");    	
    	jsContent.append("<script type=\"text/javascript\" charset=\"utf-8\">");
    	jsContent.append("var $jq = jQuery.noConflict();");
    	jsContent.append("</script>");
    	return jsContent.toString();
    }
    
    // Metodo que renderiza el body de una vista.
    public String writeBody(String body) {
    	StringBuilder bodyContent = new StringBuilder();
    	bodyContent.append("<body>");
    	bodyContent.append(writeBanner());
    	bodyContent.append("<br/>");
    	bodyContent.append("<center>");
    	bodyContent.append(body);
    	bodyContent.append("<br/>");
    	bodyContent.append(writeFooter());
    	bodyContent.append("</center>");
    	return bodyContent.toString();
    }
    
    // Metodo que renderiza el banner de una vista.
    public String writeBanner() {
    	StringBuilder banner = new StringBuilder();
    	banner.append("<div id=\"banner\">");
	    	banner.append("<center>");
	    		banner.append("<img src=\"" + contextPath +"/view/images/gatoRojo.jpg\" width=\"120\" height=\"120\"/><h1>Product Store</h1>");
	    	banner.append("</center>");
    	banner.append("</div>");
    	return banner.toString();
    }
    
    // Metodo que renderiza el footer de una vista.
    public String writeFooter() {
    	StringBuilder footer = new StringBuilder();
    	footer.append("<div id=\"footer\">");
	    	footer.append("<center>");
	    		footer.append("<a href=\"http://groups.google.com/group/gato_rojo\"><img src=\"" + contextPath +"/view/images/gato_rojo.jpg\" width=\"50\" height=\"50\"></a><br/>Developed by GatoRojo Group - 2010");
	    	footer.append("</center>");
    	footer.append("</div>");
    	return footer.toString();
    }
    
    // Metodos particulares para renderizar componentes de cada caso de uso.
    
    // Metodo que renderiza el form de Add Product.
    public String writeAddProductForm() {
    	StringBuilder formDiv = new StringBuilder();
    	formDiv.append("<div class=\"header\">");    	
	    	formDiv.append("<img src=\"" + contextPath +"/view/images/add.png\" width=\"50\" height=\"50\">&nbsp;");
	    	formDiv.append("Add Product");
    	formDiv.append("</div>");
    	formDiv.append("<hr/>");
    	formDiv.append("<div class=\"form\">");    	
			formDiv.append("<form name=\"confirmAddProductForm\" action=\"" + contextPath +"/GatoRojoPrintWriter\" method=\"get\">");
	    	
				formDiv.append("<input type=\"hidden\" name=\"action\" value=\"");
		    	formDiv.append("ADD");
		    	formDiv.append("\"><br/>");
		    	
		    	formDiv.append("<b>Product Code: </b>");
		    	formDiv.append("<input type=\"text\" name=\"productCode\" value=\"\"");		    	
		    	formDiv.append("<br/>");
		    	
		    	formDiv.append("<b>Product Name: </b>");
		    	formDiv.append("<input type=\"text\" name=\"productName\" value=\"\"");		    	
		    	formDiv.append("<br/>");
		    	
		    	formDiv.append("<b>Product Stock: </b>");
		    	formDiv.append("<input type=\"text\" name=\"productStock\" value=\"\"");		    	
		    	formDiv.append("<br/>");
		    	
		    	formDiv.append("<input type=\"submit\" value=\"Add Product\" />");
		    	
			formDiv.append("</form>");
			
			formDiv.append("<form name=\"cancelAddProductForm\" action=\"" + contextPath +"/GatoRojoPrintWriter\" method=\"get\">");
		
		    	formDiv.append("<input type=\"hidden\" name=\"action\" value=\"");
		    	formDiv.append("CANCEL_ADD");
		    	formDiv.append("\"><br/>");
		    	
		    	formDiv.append("<input type=\"submit\" value=\"Cancel\" />");		    	
			formDiv.append("</form>");		
		formDiv.append("</div>");    	
    	return formDiv.toString();
    }
    
    // Metodo que renderiza el form de Update Product.
    public String writeUpdateProductForm(Product product) {
    	StringBuilder formDiv = new StringBuilder();
    	formDiv.append("<div class=\"header\">");    	
	    	formDiv.append("<img src=\"" + contextPath +"/view/images/update.png\" width=\"50\" height=\"50\">&nbsp;");
	    	formDiv.append("Update Product");
		formDiv.append("</div>");
		formDiv.append("<hr/>");
		formDiv.append("<div class=\"form\">");    	
			formDiv.append("<form name=\"confirmUpdateProductForm\" action=\"" + contextPath +"/GatoRojoPrintWriter\" method=\"get\">");
	    	
				formDiv.append("<input type=\"hidden\" name=\"action\" value=\"");
		    	formDiv.append("UPDATE");
		    	formDiv.append("\"><br/>");
		    	
		    	formDiv.append("<input type=\"hidden\" name=\"productCode\" value=\"");
		    	formDiv.append(product.getCode());
		    	formDiv.append("\">");
		    	
		    	formDiv.append("<b>Product Code: </b>");
		    	formDiv.append(product.getCode());
		    	formDiv.append("<br/>");
		    	
		    	formDiv.append("<b>Product Name: </b>");
		    	formDiv.append("<input type=\"text\" name=\"productName\" value=\"");
		    	formDiv.append(product.getName());
		    	formDiv.append("\"><br/>");
		    	
		    	formDiv.append("<b>Product Stock: </b>");
		    	formDiv.append("<input type=\"text\" name=\"productStock\" value=\"");
		    	formDiv.append(product.getStock());
		    	formDiv.append("\"><br />");
		    	
		    	formDiv.append("<input type=\"submit\" value=\"Update Product\" />");
		    	
			formDiv.append("</form>");
			
			formDiv.append("<form name=\"cancelUpdateProductForm\" action=\"" + contextPath +"/GatoRojoPrintWriter\" method=\"get\">");
		
		    	formDiv.append("<input type=\"hidden\" name=\"action\" value=\"");
		    	formDiv.append("CANCEL_UPDATE");
		    	formDiv.append("\"><br/>");
		    	
		    	formDiv.append("<input type=\"submit\" value=\"Cancel\" />");		    	
			formDiv.append("</form>");		
		formDiv.append("</div>");    	
    	return formDiv.toString();
    }       
    
    // Metodo que renderiza el form de Confirm Delete Product.
    public String writeConfirmDeleteProductForm(int code) {
    	StringBuilder formDiv = new StringBuilder();    	
    	formDiv.append("<div class=\"header\">");    	
	    	formDiv.append("<img src=\"" + contextPath +"/view/images/delete.png\" width=\"50\" height=\"50\">&nbsp;");
	    	formDiv.append("Delete Product");
		formDiv.append("</div>");
		formDiv.append("<hr/>");
		formDiv.append("<p>");
			formDiv.append("<center>");
				formDiv.append("<img src=\"" + contextPath +"/view/images/warning.png\" width=\"60\" height=\"60\">&nbsp;");
				formDiv.append("<br/>");
				formDiv.append("Are you sure you want to delete the product with code <b>");
				formDiv.append(code);
				formDiv.append("</b>?");
			formDiv.append("</center>");				
		formDiv.append("</p>");
		formDiv.append("<div class=\"form\">");    	
	    	formDiv.append("<form name=\"confirmDeleteProductForm\" action=\"" + contextPath +"/GatoRojoPrintWriter\" method=\"get\">");
	    	
		    	formDiv.append("<input type=\"hidden\" name=\"action\" value=\"");
		    	formDiv.append("DELETE");
		    	formDiv.append("\"><br/>");
		    	
		    	formDiv.append("<input type=\"hidden\" name=\"productCode\" value=\"");
		    	formDiv.append(code);
		    	formDiv.append("\">");
		    	
		    	formDiv.append("<input type=\"submit\" value=\"Yes\" />");		    	
    		formDiv.append("</form>");
    		
    		formDiv.append("<form name=\"cancelDeleteProductForm\" action=\"" + contextPath +"/GatoRojoPrintWriter\" method=\"get\">");
    	
		    	formDiv.append("<input type=\"hidden\" name=\"action\" value=\"");
		    	formDiv.append("CANCEL_DELETE");
		    	formDiv.append("\"><br/>");		    			    			    			  
		    	
		    	formDiv.append("<input type=\"submit\" value=\"No\" />");		    	
			formDiv.append("</form>");		
		formDiv.append("</div>");
    	return formDiv.toString();
    }
    
    // Metodo que renderiza el form de List Product.
    public String writeProductList(List<Product> products) {
    	StringBuilder listDiv = new StringBuilder();
    	listDiv.append("<div id=\"table\">");    	    
    	listDiv.append("<table border=\"1\">");
	    	listDiv.append("<tr>");
	    	
		    	listDiv.append("<th>");
		    	listDiv.append("Code");
		    	listDiv.append("</th>");
		    	
		    	listDiv.append("<th>");
		    	listDiv.append("Name");
		    	listDiv.append("</th>");
		    	
		    	listDiv.append("<th>");
		    	listDiv.append("Stock");
		    	listDiv.append("</th>");
	    	
	    	listDiv.append("</tr>");
	    	
	    	for(Product product:products) {
	    		listDiv.append("<tr>");
		    	
			    	listDiv.append("<td>");
			    	listDiv.append(product.getCode());
			    	listDiv.append("</td>");
			    	
			    	listDiv.append("<td>");
			    	listDiv.append(product.getName());
			    	listDiv.append("</td>");
			    	
			    	listDiv.append("<td>");
			    	listDiv.append(product.getStock());
			    	listDiv.append("</td>");
	    	
		    	listDiv.append("</tr>");
	    	}
	    	
	    listDiv.append("</table>");
	    listDiv.append("</div>");
	    return listDiv.toString();
    }
    
    // Metodo que renderiza el form de Add Product en la lista de Products.
    public String writeAddForm() {
    	StringBuilder formDiv = new StringBuilder();
    	formDiv.append("<i>Add Product:</i>");
    	formDiv.append("<div class=\"form\">");
	    	formDiv.append("<form name=\"addForm\" action=\"" + contextPath +"/GatoRojoPrintWriter\" method=\"get\">");
	    	
		    	formDiv.append("<input type=\"hidden\" name=\"action\" value=\"");
		    	formDiv.append("SHOW_ADD");
		    	formDiv.append("\"><br/>");		    			    			   
		    	formDiv.append("<input type=\"image\" src=\"" + contextPath +"/view/images/add.png\" height=\"40\" width=\"40\" border=\"0\" alt=\"Add Product\">");
		    	
    		formDiv.append("</form>");
    	formDiv.append("</div>");
    	return formDiv.toString();
    }
    
    // Metodo que renderiza el form de Update Product en la lista de Products.
    public String writeUpdateForm() {
    	StringBuilder formDiv = new StringBuilder();
    	formDiv.append("<i>Update Product:</i>");
    	formDiv.append("<div class=\"form\">");
	    	formDiv.append("<form name=\"updateForm\" action=\"" + contextPath +"/GatoRojoPrintWriter\" method=\"get\">");
	    	
		    	formDiv.append("<input type=\"hidden\" name=\"action\" value=\"");
		    	formDiv.append("SHOW_UPDATE");
		    	formDiv.append("\"><br/>");
		    	
		    	formDiv.append("<b>Product Code: </b>");
		    	formDiv.append("<input type=\"text\" name=\"productCode\" value=\"\"");		    	
		    	formDiv.append("<br/>");
		    	
		    	formDiv.append("<input type=\"image\" src=\"" + contextPath +"/view/images/update.png\" height=\"40\" width=\"40\" border=\"0\" alt=\"Update Product\">");
		    	
    		formDiv.append("</form>");
    	formDiv.append("</div>");
    	return formDiv.toString();
    }
    
    // Metodo que renderiza el form de Delete Product.
    public String writeDeleteProductForm() {
    	StringBuilder formDiv = new StringBuilder();
    	formDiv.append("<i>Delete Product:</i>");
    	formDiv.append("<div class=\"form\">");
	    	formDiv.append("<form name=\"deleteProductForm\" action=\"" + contextPath +"/GatoRojoPrintWriter\" method=\"get\">");
	    	
		    	formDiv.append("<input type=\"hidden\" name=\"action\" value=\"");
		    	formDiv.append("SHOW_DELETE");
		    	formDiv.append("\"><br/>");
		    	
		    	formDiv.append("<b>Product Code: </b>");
		    	formDiv.append("<input type=\"text\" name=\"productCode\" value=\"\"");		    	
		    	formDiv.append("<br/>");		    			    
		    	
		    	formDiv.append("<input type=\"image\" src=\"" + contextPath +"/view/images/delete.png\" height=\"40\" width=\"40\" border=\"0\" alt=\"Delete Product\">");
		    	
    		formDiv.append("</form>");
    	formDiv.append("</div>");
    	return formDiv.toString();
    }
        
    // Metodo que renderiza un mensaje enviado desde un caso de uso o una operacion de cancelacion.
    public String writeMessage(String message) {
    	StringBuilder messageDiv = new StringBuilder();
    	messageDiv.append("<div id=\"message\">");    	
	    	messageDiv.append("<img src=\"" + contextPath +"/view/images/info.png\" width=\"50\" height=\"50\">&nbsp;");
	    	messageDiv.append(message);
    	messageDiv.append("</div>");
    	return messageDiv.toString();    	    
    }
                     
    public void doPost (HttpServletRequest request,
                       HttpServletResponse response) throws ServletException, IOException {    
    }

    public void init() throws ServletException {
    }

    public void destroy() {
    }
}